﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Luminoise;
using System.Drawing;
using System.Diagnostics;
using System.Drawing.Imaging;

namespace Luminoise_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            int imageSize = 1024;

            Single3[] input = new Single3[imageSize * imageSize];
            for (int i = 0; i < input.Length; i++)
            {
                input[i] = new Single3((i % imageSize) / (imageSize - 1.0f) * 2 - 1, (i / imageSize) / (imageSize - 1.0f) * 2 - 1, 0.0f);
                //float lsqr = input[i].X * input[i].X + input[i].Y * input[i].Y;
                //if (lsqr <= 1.0f)
                //    input[i].Z = (float)Math.Sqrt(1.0f - lsqr);
            }

            Module module = new RidgedMultifractal(4, 5, 2.0f, 0.5f, 1.0f) * 0.5f + 0.5f;
            NoiseProgram program = new NoiseProgram(module);

            Stopwatch timer = new Stopwatch();
            timer.Start();
            program.Compile();
            timer.Stop();
            Console.WriteLine("Noise generation of {0}x{0} values completed in {1}", imageSize, timer.Elapsed);
            float[] values = program.GetValues(input);

            Bitmap bitmap = new Bitmap(imageSize, imageSize);
            for (int i = 0; i < input.Length; i++)
            {
                // Gradients
                //float length = (float)Math.Sqrt(values[i].X * values[i].X + values[i].Y * values[i].Y + values[i].Z * values[i].Z);
                //values[i].X /= length;
                //values[i].Y /= length;
                //values[i].Z /= length;
                //int valx = (int)((values[i].X * 0.5f + 0.5f) * 255.0f);
                //int valy = (int)((values[i].Y * 0.5f + 0.5f) * 255.0f);
                //int valz = (int)((values[i].Z * 0.5f + 0.5f) * 255.0f);
                //bitmap.SetPixel(i % imageSize, i / imageSize, Color.FromArgb(valx, valy, valz));

                // Normal Noise
                if (values[i] < 0.0f)
                    values[i] = 0.0f;
                if (values[i] > 1.0f)
                    values[i] = 1.0f;

                int val = (int)(values[i] * 255.0f);

                bitmap.SetPixel(
                    i % imageSize,
                    i / imageSize,
                    Color.FromArgb(val, val, val));

                //// Colored Noise
                //bitmap.SetPixel(
                //    i % imageSize,
                //    i / imageSize,
                //    Color.FromArgb(
                //        255,
                //        lerp(255, 0, values[i]),
                //        lerp(0, 255, (float)Math.Sin(values[i] * 31.4f) * 0.5f + 0.5f),
                //        lerp(0, 255, values[i])));
            }
            bitmap.Save("Output.bmp");

            Process.Start("Output.bmp");

            program.Dispose();
        }

        static int lerp(int min, int max, float value)
        {
            return (int)(min + (max - min) * value);
        }
    }
}
